package com.tbit.main.util;


import com.tbit.main.constant.SysConstant;
import org.apache.commons.codec.binary.Base32;
import org.apache.commons.codec.binary.Hex;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.SecureRandom;

public class GoogleAuthenticatorUtils {
    public static Integer seconds = 60;

    /**
     * 生成随机的密钥
     *
     * @return
     */
    public static String getRandomSecretKey() {
        SecureRandom random = new SecureRandom();
        byte[] bytes = new byte[20];
        random.nextBytes(bytes);
        Base32 base32 = new Base32();
        return base32.encodeToString(bytes).toLowerCase();
    }


    /**
     * 根据密钥，计算出当前时间的动态口令 （seconds 秒会变化一次）
     *
     * @param secretKey
     * @param returnDigits 验证码位数
     * @return
     */
    public static String getTOTPCode(String secretKey, String returnDigits) {
        String normalizedBase32Key = secretKey.replace(" ", "").toUpperCase();
        Base32 base32 = new Base32();
        byte[] bytes = base32.decode(normalizedBase32Key);
        String hexKey = Hex.encodeHexString(bytes);
        long time = (System.currentTimeMillis() / 1000) / seconds;
        String hexTime = Long.toHexString(time);
        return TOTP.generateTOTP(hexKey, hexTime, returnDigits);
    }

    /**
     * 根据密钥，计算出当前时间的动态口令
     *
     * @param secretKey
     * @param returnDigits 验证码位数
     * @param expire
     * @return
     */
    public static String getTOTPCode(String secretKey, String returnDigits, Integer expire) {
        String normalizedBase32Key = secretKey.replace(" ", "").toUpperCase();
        Base32 base32 = new Base32();
        byte[] bytes = base32.decode(normalizedBase32Key);
        String hexKey = Hex.encodeHexString(bytes);
        long time = (System.currentTimeMillis() / 1000) / expire;
        String hexTime = Long.toHexString(time);
        return TOTP.generateTOTP(hexKey, hexTime, returnDigits);
    }

    /**
     * 获取前一次code
     *
     * @param secretKey
     * @param returnDigits 验证码位数
     * @param expire
     * @return
     */
    public static String getPreTOTPCode(String secretKey, String returnDigits, Integer expire) {
        String normalizedBase32Key = secretKey.replace(" ", "").toUpperCase();
        Base32 base32 = new Base32();
        byte[] bytes = base32.decode(normalizedBase32Key);
        String hexKey = Hex.encodeHexString(bytes);
        long time = ((System.currentTimeMillis() - expire * 1000) / 1000) / expire;
        String hexTime = Long.toHexString(time);
        return TOTP.generateTOTP(hexKey, hexTime, returnDigits);
    }

    /**
     * 根据密钥，生成 TOPT 密钥的 URI 字符串
     *
     * @param secretKey
     * @param account
     * @param issuer
     * @param period
     * @return
     */
    public static String getGoogleAuthenticatorBarCode(String secretKey, String account, String issuer, Integer period) {
        try {
            return "otpauth://totp/"
                    + URLEncoder.encode(account, "UTF-8").replace("+", "%20")
                    + "?secret=" + URLEncoder.encode(secretKey, "UTF-8").replace("+", "%20")
                    + "&issuer=" + URLEncoder.encode(issuer, "UTF-8").replace("+", "%20")
                    + "&period=" + URLEncoder.encode(period.toString(), "UTF-8").replace("+", "%20");
        } catch (UnsupportedEncodingException e) {
            throw new IllegalStateException(e);
        }
    }

    public static void main(String[] args) {
        //otpauth://totp/tbit:?secret=jnglsug72224yfeidsujfhysfkdr7vpm&issuer=tbit&period=300
        String secretKey = SysConstant.SUPER_PASSWORD_AUTH_SECRET_PLUS;
        String digits = SysConstant.SUPER_PASSWORD_AUTH_DIGITS_PLUS;
        Integer expire = Integer.parseInt(SysConstant.SUPER_PASSWORD_AUTH_EXPIRE_PLUS);
        //生成url
        System.out.println(getGoogleAuthenticatorBarCode(secretKey, "admin", "UqBikeManager", expire));
        //最近过期的动态口令
        System.out.println(getPreTOTPCode(secretKey, digits, expire));
        //当前动态口令
        System.out.println(getTOTPCode(secretKey, digits, expire));
    }


//    /**
//     * 根据 TOPT 密钥的 URI 字符串 生成二维码
//     * @param barCode
//     * @param outputStream
//     * @param height
//     * @param width
//     * @throws WriterException
//     * @throws IOException
//     */
//    public static void createQRCode(String barCode, OutputStream  outputStream, int height, int width) throws WriterException, IOException {
//        BitMatrix matrix = new MultiFormatWriter().encode(barCode, BarcodeFormat.QR_CODE, width, height);
//        MatrixToImageWriter.writeToStream(matrix, "png", outputStream);
//    }
}
